package sy4_Creational_Pattern.factory.abstractFactory;
/*
 * 工厂方法模式中，所有具体工厂只生产一种相同类型的产品。
 * 抽象工厂模式中，所有具体工厂生产多种相同类型的产品，存在产品等级结构和产品族概念。
 * 
 * 产品等级结构由不同工厂生产的同一类型产品组成，如海尔电视机——TCL电视机...。
 * 产品等级结构：指产品的继承结构，如抽象的电视机与具体品牌的电视机之间构成了一个产品等级结构。
 * 对应于抽象产品ProductA的产品等级结构命名：ConcreteProductA1、ConcreteProductA2，...
 * 
 * 一组相关联的产品，如海尔电视机、海尔空调器...，组成一个产品族。
 * 产品族：同一工厂生产、位于不同产品等级结构中的的不同产品。
 * 简明地说，产品族是指同一工厂生产多种产品。
 * 
 * 工厂方法模式只有一个产品等级结构，因此，工厂方法模式是抽象工厂模式的退化。
 * 
 * 如果增加新的产品（如洗衣机），则需要添加相应的抽象产品及其子类。
 * 同时，还需要在抽象工厂里添加新的抽象方法，在具体工厂重写新增的抽象方法。
 * 因此，抽象工厂模式属于对象创建型模式。抽象工厂模式不支持添加新的产品类别。
 * 
 * 如果增加新的品牌（产品簇）——抽象工厂的子类，如Sony工厂，只需要同时增加该工厂生产的产品类，则符合开闭原则（如同工厂方法模式）。
 * 
 */

abstract class AbstractProductA {  //角色1：抽象产品（电视）
    public abstract void methodA();  //播放
}

class ConcreteProductA1 extends AbstractProductA {  //角色2：具体产品（如海尔电视）
    @Override
    public void methodA() {
        System.out.println("海尔电视机播放中......");
    }
}

class ConcreteProductA2 extends AbstractProductA {  //角色2：具体产品（如TCL电视）
    @Override
    public void methodA() {
        System.out.println("TCL电视机播放中......");
    }
}
/*class ConcreteProductA3 extends AbstractProductA {  //角色2：具体产品（Sony电视），供扩展用
    @Override
    public void methodA() {
        System.out.println("Sony电视机播放中......");
    }
}*/

abstract class AbstractProductB {   //角色1：抽象产品（空调）
    public abstract void methodB();  //调温
}

class ConcreteProductB1 extends AbstractProductB {  //角色2：具体产品（如海尔空调）
	@Override
    public void methodB() {
        System.out.println("海尔空调温度改变中......");
    }
}

class ConcreteProductB2 extends AbstractProductB {  //角色2：具体产品（TCL空调）
	@Override
    public void methodB() {
        System.out.println("TCL空调温度改变中......");
    }
}
/*class ConcreteProductB3 extends AbstractProductB {  //角色2：具体产品（Sony空调），供扩展用
	@Override
    public void methodB() {
        System.out.println("Sony空调温度改变中......");
    }
}*/

abstract class AbstractFactory { //角色3：抽象工厂
    public abstract AbstractProductA createProductA(); //生产电视
    public abstract AbstractProductB createProductB(); //生产空调
}

class ConcreteFactory1 extends AbstractFactory {   //角色4：具体工厂（海尔）
    @Override
    public AbstractProductA createProductA() {
        System.out.println("海尔工厂生产海尔电视机");
        return new ConcreteProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        System.out.println("海尔工厂生产海尔空调");
        return new ConcreteProductB1();
    }
}

class ConcreteFactory2 extends AbstractFactory {  //角色4：具体工厂（TCL）
    @Override
    public AbstractProductA createProductA() {
        System.out.println("TCL工厂生产TCL电视机");
        return new ConcreteProductA2();
    }
    @Override
    public AbstractProductB createProductB() {
        System.out.println("TCL工厂生产TCL空调");
        return new ConcreteProductB2();
    }
}
/*class ConcreteFactory3 extends AbstractFactory {   //角色4：具体工厂（Sony）：供扩展用
    @Override
    public AbstractProductA createProductA() {
        System.out.println("Sony工厂生产Sony电视机");
        return new ConcreteProductA3();
    }
    @Override
    public AbstractProductB createProductB() {
        System.out.println("Sony工厂生产Sony空调");
        return new ConcreteProductB3();
    }
}*/

public class Client {   //客户端
    public static void main(String args[]) {
    	AbstractFactory factory = new ConcreteFactory1();  //创建具体工厂
    	AbstractProductA productA = factory.createProductA();  //定义产品族对象
        productA.methodA();
        AbstractProductB productB = factory.createProductB();  //定义产品族对象
        productB.methodB();
        System.out.println("======================");

        try { //适当修改配置文件，做运行测试
            factory = (AbstractFactory) XMLUtil.getBean();  //创建具体工厂
            productA = factory.createProductA();
            productA.methodA();
            productB = factory.createProductB();
            productB.methodB();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}